package cn.arifun.config;

import cn.arifun.handler.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;

/**
 * @Author: 漆原
 * @Description: springSecurity默认配置
 * @DateTime: 2024/10/1 13:46
 **/
@Configuration
public class SpringSecurityConfig {

//    @Bean
//    public UserDetailsService userDetailsService() {
//        //基于内存的账户定义
//        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
//        //如果使用createUser方法，且未指定密码加密，需要给密码加前缀
//        //java.lang.IllegalArgumentException: You have entered a password with no PasswordEncoder. If that is your intent, it should be prefixed with `{noop}`.
//        inMemoryUserDetailsManager.createUser(User.withUsername("wlp").password("{noop}admin123").roles("USER").build());
//        return inMemoryUserDetailsManager;
//    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeHttpRequests(
                authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry
                        .anyRequest()   //对所有请求进行权鉴
                        .authenticated())   //已认证请求自动授权
        ;

        httpSecurity.formLogin(formLogin -> {
            formLogin.loginPage("/login").permitAll()   //访问该页面无需授权
                    .usernameParameter("username")  //自定义用户名字段名，默认username
                    .passwordParameter("password")  //自定义密码字段名，默认password
                    .failureUrl("/login?error") //校验失败跳转地址
                    .successHandler(new JsonAuthenticationSuccessHandler()) //指定自定义校验成功处理器
                    .failureHandler(new JsonAuthenticationFailureHandler()) //指定自定义校验失败处理器
            ;
        });

        //注销成功处理
        httpSecurity.logout(logout -> logout.logoutSuccessHandler(new JsonLogoutSuccessHandler()));

        //无请求权限处理
        httpSecurity.exceptionHandling(configurer -> configurer.authenticationEntryPoint(new JsonAuthenticationEntryPointHandler()));

        //并发登录处理
        httpSecurity.sessionManagement(session -> {
            session.maximumSessions(1)  //允许账号同时在线数
                    .expiredSessionStrategy(new JsonSessionInformationExpiredStrategy());
        });

        //跨域
        httpSecurity.cors(Customizer.withDefaults());

        //关闭csrf防御
        httpSecurity.csrf(AbstractHttpConfigurer::disable);
        return httpSecurity.build();
    }
}
